import java.util.Properties;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;

/* Test SMTP Connectivity for following ports: 
 * 		port 25 : normal SMTP (through yahoo)
 * 		port 465 : SMTPS (through gmail)
 * 		port 587 : SMTP with TLS (through gmail)
 * 
 *	Usage for this class is as follows: 
 * 		1) Create new class
 * 		2) Call setProperties(int port)
 * 		3) call runtests (int numberOfTests)
 */
public class AllSMTPConnectivity implements Runnable {
	
	ConnectionStatus internetStatus = new ConnectionStatus();
	
	private String HOST_NAME;
	private int HOST_PORT;
	private String AUTH_USER;
	private String AUTH_PWD;
	
	private Properties props = new Properties();
	
	private boolean badFlag = true; // used for the case that the user provides a bad port
	
	
	// for thread synchronization
	ResultsTable sharedTable = new ResultsTable();
	private int numTests;
	static CyclicBarrier barrier;
	String SMTP_KEY;
	
	
	public AllSMTPConnectivity(ResultsTable r, CyclicBarrier b, int n) {
		sharedTable = r;
		barrier = b;
		numTests = n;
	}
	
	
	@Override
	public void run() {
		try {
			internetStatus = runTests(numTests);
		} catch (Exception e) {
		}
			sharedTable.addResult(SMTP_KEY, internetStatus);
		
		try {
			barrier.await();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (BrokenBarrierException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		
	}

	public void setProperties(int port) {
		if (port == 25) {
			SMTP_KEY = "smtp_25";
			badFlag = false;
			HOST_NAME = "smtp.mail.yahoo.com";
			HOST_PORT = 25;
			AUTH_USER = "mifcais@yahoo.com";
			AUTH_PWD = "COMSE6181";			
//			props.put("mail.transport.protocol", "smtp");
	        props.put("mail.smtp.host", HOST_NAME);
	        props.put("mail.smtp.auth", "true");
	        props.put("mail.smtp.quitwait", "false");
//	        props.put("mail.smtp.starttls.enable", "true");
	        
		} else if (port == 465) {
			SMTP_KEY = "smtp_465";
			badFlag = false;
			HOST_NAME = "smtp.gmail.com";
//			HOST_NAME = "smtp.googlemail.com";
			HOST_PORT = 465;
			AUTH_USER = "mifcais2@gmail.com";
			AUTH_PWD = "COMSE6181";			
	        props.put("mail.transport.protocol", "smtps");
//	        props.put("mail.smtps.host", HOST_NAME);
//	        props.put("mail.smtps.auth", "true");
//	        props.put("mail.smtps.quitwait", "false");
//	        props.put("mail.smtp.starttls.enable", "true");
			props.put("mail.smtp.host", "smtp.gmail.com");
			props.put("mail.smtp.socketFactory.port", "465");
			props.put("mail.smtp.socketFactory.class","javax.net.ssl.SSLSocketFactory");
			props.put("mail.smtp.auth", "true");
//			props.put("mail.smtp.port", "465");
	        
		} else if (port == 587) {
			SMTP_KEY = "smtp_587";
			badFlag = false;
			HOST_NAME = "smtp.gmail.com";
			HOST_PORT = 587;
			AUTH_USER = "mifcais2@gmail.com";
			AUTH_PWD = "COMSE6181";			
//	        props.put("mail.transport.protocol", "smtp");
//	        props.put("mail.smtp.host", HOST_NAME);
	        props.put("mail.smtp.auth", "true");
	        props.put("mail.smtp.starttls.enable", "true");
//	        props.put("mail.smtp.quitwait", "false");
		} else {
			System.out.println("You have provided a bad port");
			badFlag = true;
		}
	}
				
	public ConnectionStatus runTests (int n){
		
		System.out.println("In SMTP RUN for port " + HOST_PORT);
		for (int i = 0; i < n; i++){
			// run the test n times
			if (isConnected() && !badFlag) {
				this.internetStatus.addPassedAttempt();
			} else {
				this.internetStatus.addFailedAttempt();
			}
		}			
		return this.internetStatus;	
	}
	
    private boolean isConnected(){
    	
    	boolean result = false; // initialize result as false
    	
        Session mailSession = Session.getDefaultInstance(props);        
        mailSession.setDebug(false);
       // System.out.println("THIS IS A TEST IN SMTP JUST BEFORE WE CONNECT    --- HOST_PORT: " + HOST_PORT);
            
        try {
        	Transport transport;
        	if (HOST_PORT == 587) {
        		transport = mailSession.getTransport("smtp");
        	}
        	else if (HOST_PORT == 465) {
        		transport = mailSession.getTransport("smtps");
        	}
        	else { // HOST_PORT == 25
        		transport = mailSession.getTransport("smtp");
        	}
        	
			transport.connect(HOST_NAME, HOST_PORT, AUTH_USER, AUTH_PWD);
			transport.close();
		} catch (Exception e) {
			return false;
		}
        
        /* The commands below actually send a message to the specified address.
         * However, what we need to do is simply check for connection.			
        MimeMessage message = new MimeMessage(mailSession);
        message.setSubject("Testing SMTP-SSL");
        message.setContent("This is a test", "text/plain");
        message.addRecipient(Message.RecipientType.TO, new InternetAddress("heliosaurus@gmail.com"));        
        transport.sendMessage(message, message.getRecipients(Message.RecipientType.TO));
        */
        
        
        
        result = true; // if we reached that point ==> everything went ok. 
        return result;
    }
}